import React, { BaseHTMLAttributes, ChangeEvent, forwardRef, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
import { Tree, Tabs, Button, Input, Tooltip, Modal } from 'antd';
import { DownOutlined, ExclamationCircleOutlined, ExpandAltOutlined, PartitionOutlined, SettingOutlined, VerticalAlignBottomOutlined, VerticalAlignMiddleOutlined } from '@ant-design/icons'
import './TopicSliderBar.scss'
import { DocConfig, DocInstance, TopicNodeActionType, TopicType } from '../../../utils/types';
import {
    addTreePropertyForList, commonErrorMsg, commonSuccessMsg,
    deepCloneV2, dfsRecursive, dfsRecursiveFromInner, filterTree,
    findHalfCheckedKeys, findLastTreeNode, findTreePathByNodeId, generateTreeData,
    getChangeEventValue, getNodeChildDeviceNodeCheckedCount, getNodeChildDeviceNodeCount, isEmpty, makeClassNameList,
    swapListElements, toastShort, tree2List
} from '../../../utils';
import comDocContext from '../../../context/DocContext';
import TopicTreeContextMenu from '../../../components/context-menu/TopicTreeContextMenu';
import useReSize from '../../../hooks/useResize';
import TopicSettingPopover from '../../../components/popover/TopicSettingPopover';
import AddTopicMoal from './sider-modal/AddTopicMoal';
import ReNameTopicModal from './sider-modal/ReNameTopicModal';
import useStateDebounce from '../../../hooks/useStateDebounce';
import { Resizable } from 'react-resizable';
import { processDocInstanceBeforeUpdate } from '../word-editor/editor-doc-item-generate';
import { throttle } from 'lodash';
import { ConnectionPoint, ExpandLeft, ExpandRight, SettingConfig, SlidingHorizontal } from '@icon-park/react';
import { useSearchParams } from 'react-router-dom';
import { DocItem } from '../../slate-editor';
import DeviceNodeManagePopUp from './sider-modal/DeviceNodeManagePopUp';
import DeviceNodeManageModal from './sider-modal/DeviceNodeManageModal';
import DeviceNodeManageModalV2 from './sider-modal/DeviceNodeManageModalV2';

interface Props {
    onHandleResize?: Function
}

const { Search } = Input;

const TopicSiderBar = (props: Props, ref: any) => {

    const contextMenuRef = useRef<any>(null);

    const {
        //规划数据实例
        comDocInstance,
        _setComDocInstance,
        //规划配置信息
        comDocConfig,
        currentFocusedDocItem,
        _setComFocusTopicNode,
        _setComDocConfig,
        _setComFocusLayoutTopicNode,
        comFocusLayoutTopicNode,
        
    } = useContext(comDocContext);

    const {
        onHandleResize,
    } = props;

    const tempComDocInstance = useRef<DocInstance>(null);

    const topicSiderRef = useRef(null);
    const topicSettingPopoverRef = useRef(null);
    const addTopicModalRef = useRef<any>(null);
    const renameTopicModalRef = useRef<any>(null);
    const deviceNodeManagePopUpRef = useRef<any>(null);
    const deviceNodeManageModalRef = useRef<any>(null);
    const isTopicSliderDragging = useRef(false);

    const hasSetDefaultTabKey = useRef(false);

    const tempTopicList = useRef<TopicType[]>(null);

    const [topicList, setTopicList] = useState<TopicType[]>([]);
    //选中的设施设备
    const [checkedTopicIdList, setCheckedTopicIdList] = useState<string[]>([]);
    //树组件的选择id（强校验）
    const [topicTreeCheckedNodeIdList, setTopicTreeCheckedNodeIdList] = useState<string[]>([]);
    //设置按钮的坐标位置
    const [topicSettingBtnPosition, setTopicSettingBtnPosition] = useState<{ x: number, y: number }>({ x: 0, y: 0 });
    //当前大纲展开的节点
    const [currentTopicTreeNodeExpandedKeys, setCurrentTopicTreeNodeExpandedKeys] = useState<string[]>([]);
    //所有大纲展开的节点
    const [allTopicTreeExpandedKeys, setAllTopicTreeExpandedKeys] = useState<string[]>([]);
    //当前选中的topic
    const [currentSelectedTopicNode, setCurrentSelectedTopicNode] = useState<TopicType>(null);
    //当前高亮的topic
    const [currentHighLightTopicNode, setCurrentHighLightTopicNode] = useState<TopicType>(null)
    //选择的树节点操作类型
    const [currentTreeNodeActionType, setCurrentTreeNodeActionType] = useState<TopicNodeActionType>(null);

    const allTopicTreeSelectNodeIdList = useRef<string[]>([]);
    const [topicSearchValue, setTopicSearchValue] = useState<string>('');
    const [currentTopicSearchValue, setCurrentTopicSearchValue] = useState<string>('');
    const [filteredForAllTopicTree, setFilteredForAllTopicTree] = useState<TopicType[]>([]);
    const [filteredForAllTopicTreeExpandedKeys, setFilteredForAllTopicTreeExpandedKeys] = useState<string[]>([]);
    const [filteredForCurrentTopicTree, setFilteredForCurrentTopicTree] = useState<TopicType[]>([]);
    const [filteredForCurrentTopicTreeExpandedKeys, setFilteredForCurrentTopicTreeExpandedKeys] = useState<string[]>([]);

    const saveSideBarCacheDelayTimer = useRef<any>(null);
    const toastDelayTimer = useRef<any>(null);

    const currentTopicTreeRef = useRef(null);
    const tempNavType = useRef("excel");

    const [currentcomDocConfig, setCurrentcomDocConfig] = useState<DocConfig>({
        updateComponentName: 'TopicSliderBar',
        docBaseConfigInfo: {}
    });

    const updateComDocInstanceDelayTimer = useRef(null);

    const [delayUpdateComDocInstance, setDelayUpdateComDocInstance] = useState<DocInstance>(comDocInstance);

    const debouncedComDocInstance = useStateDebounce(delayUpdateComDocInstance, 100);

    const topicContainerSize = useReSize(topicSiderRef)

    const [currentActiveTabKey, setCurrentActiveTabKey] = useState<'currentTopic' | 'allTopic'>('currentTopic');

    const [sideBarSwitched, setSideBarSwitched] = useState<0 | 1 | 2>(0);

    const [windowFullHeight, setWindowFullHeight] = useState<number>(0);

    const [draggingNodeKey, setDraggingNodeKey] = useState(null);

    const selectTreeTimer = useRef(null);

    const tempFocusedDocItem = useRef<DocItem>(null);

    const [currentTopicTreeActiveNodeKey, setCurrentTopicTreeActiveNodeKey] = useState("");

    const [toolTipIsOpen, setToolTipIsOpen] = useState(false);

    useEffect(() => {
        setWindowFullHeight(window.innerHeight);
        return () => {
            selectTreeTimer.current && clearTimeout(selectTreeTimer.current);
            toastDelayTimer.current && clearTimeout(toastDelayTimer.current);
            saveSideBarCacheDelayTimer.current && clearTimeout(saveSideBarCacheDelayTimer.current);
            updateComDocInstanceDelayTimer.current && clearTimeout(updateComDocInstanceDelayTimer.current)
        }
    }, [])

    // const [searchParams, setSearchParams] = useSearchParams();

    // useEffect(() => {
    //     const currentNavType = searchParams.get("screen");
    //     const sideTabKey = searchParams.get("sidetab");
    //     if (!hasSetDefaultTabKey.current) {
    //         hasSetDefaultTabKey.current = true;
    //         //@ts-ignore
    //         setCurrentActiveTabKey(sideTabKey)
    //     } else {
    //         if (tempNavType.current !== currentNavType) {
    //             tempNavType.current = currentNavType;
    //             if (currentNavType === 'word') {
    //                 setCurrentActiveTabKey("currentTopic")
    //             }
    //         }
    //     }

    // }, [searchParams]);

    useEffect(() => {
        if (
            isEmpty(comDocInstance) ||
            (comDocInstance.updateComponentName && comDocInstance.updateComponentName == 'TopicSliderBar') ||
            (isEmpty(comDocInstance.topicList) || comDocInstance.topicList.length == 0)
        ) {
            return;
        }
        let _tempComDocInstance: DocInstance = deepCloneV2(comDocInstance);
        let tempCheckedTopicIdList = _tempComDocInstance.topicList
            .filter(topic => topic.checked)
            .map(topic => topic.id);
        tempTopicList.current = _tempComDocInstance.topicList;
        setTopicList(_tempComDocInstance.topicList);
        tempComDocInstance.current = _tempComDocInstance;
        setTopicTreeCheckedNodeIdList(tempCheckedTopicIdList);
        allTopicTreeSelectNodeIdList.current = tempCheckedTopicIdList;
    }, [comDocInstance]);

    useEffect(() => {
        if (isEmpty(comDocConfig) || comDocConfig.updateComponentName == 'TopicSliderBar') {
            return;
        }
        setCurrentcomDocConfig(deepCloneV2(comDocConfig));
    }, [comDocConfig])

    useEffect(() => {
        let tempTopciTreeData = generateTreeData(addTreePropertyForList(tempTopicList.current));
        const halfCheckeNodeList: string[] = findHalfCheckedKeys(tempTopciTreeData, topicTreeCheckedNodeIdList);
        setCheckedTopicIdList(topicTreeCheckedNodeIdList.concat(halfCheckeNodeList))
        tempTopicList.current.forEach(topic => {
            if (topicTreeCheckedNodeIdList.includes(topic.id)) {
                topic.checked = true;
            } else {
                topic.checked = false;
            }
        })
        tempComDocInstance.current.topicList = tempTopicList.current;
        // if (comDocInstance && topicList.length) {
        //     if (
        //         comDocConfig.docExtraConfigInfo &&
        //         !comDocConfig.docExtraConfigInfo.hasOpenTopicManageModal
        //     ) {
        //         deviceNodeManageModalRef.current.openModal({
        //             type: 'topicList',
        //             topicList: deepCloneV2(tempTopicList.current),
        //         })
        //         let _tempComDocConfig = comDocConfig;
        //         _tempComDocConfig.docExtraConfigInfo.hasOpenTopicManageModal = true;
        //         handleUpdateComDocConfig(_tempComDocConfig);
        //     }
        // }
    }, [topicList]);

    useEffect(() => {
        if(comFocusLayoutTopicNode && comFocusLayoutTopicNode.topic && comFocusLayoutTopicNode.from !== 'topic'){
            console.log("comFocusLayoutTopicNode--->", comFocusLayoutTopicNode)
            autoFoucsTagetTreeNode(comFocusLayoutTopicNode.topic.id)
        }
    }, [comFocusLayoutTopicNode]);

    const handleUpdateComDocConfig = (newDocConfig: DocConfig) => {
        let filterDoConfig = { ...newDocConfig };
        // delete filterDoConfig.docExtraConfigInfo.dataVerificationMap;
        delete filterDoConfig.docExtraConfigInfo.mergeBoundInfo;
        //@ts-ignore
        filterDoConfig.updateComponentName = 'TopicSiderBar';
        _setComDocConfig(filterDoConfig);
    }

    useEffect(() => {
        measureSettingBtnPosition();
    }, [topicContainerSize]);

    useEffect(() => {
        if (currentFocusedDocItem) {
            if (
                tempFocusedDocItem.current &&
                tempFocusedDocItem.current.id == currentFocusedDocItem.id
            ) {
                return;
            }
            tempFocusedDocItem.current = currentFocusedDocItem;
            // console.log("currentFocusedDocItem--->", currentFocusedDocItem)
            const nodeId = currentFocusedDocItem.id.toString().split('-')[0];
            autoFoucsTagetTreeNode(nodeId);
        }
    }, [currentFocusedDocItem]);

    const findTreeNode = (treeData: TopicType[], targetNodeId: string): TopicType => {
        let findNode = null;
        treeData.forEach(node => {
            if (node.id == targetNodeId) {
                findNode = node;
            } else if (node.children && node.children.length && !findNode) {
                let _findNode = findTreeNode(node.children, targetNodeId);
                if (_findNode) {
                    findNode = _findNode;
                }
            }
        })
        return findNode;
    }

    const autoFoucsTagetTreeNode = (targetNodeId: string) => {
        let topicNode = findTreeNode(currentTopicTree, targetNodeId);
        // console.log("topicNode--->", targetNodeId, topicNode);
        if (topicNode) {
            //1、高亮
            setCurrentSelectedTopicNode(topicNode)
            setCurrentTopicTreeActiveNodeKey(targetNodeId);
            //2、展开
            let tempCurrentTopicTreeNodeExpandedKeys = currentTopicTreeNodeExpandedKeys;
            const ids: string[] = findTreePathByNodeId(currentTopicTree, targetNodeId);
            ids.forEach(id => {
                if(!tempCurrentTopicTreeNodeExpandedKeys.includes(id)){
                    tempCurrentTopicTreeNodeExpandedKeys.push(id);
                }
            })
            setCurrentTopicTreeNodeExpandedKeys(deepCloneV2(tempCurrentTopicTreeNodeExpandedKeys))
            // if (!tempCurrentTopicTreeNodeExpandedKeys.includes(topicNode.pid)) {
            //     tempCurrentTopicTreeNodeExpandedKeys.push(topicNode.pid);
            //     tempCurrentTopicTreeNodeExpandedKeys.push(topicNode.id);
            //     // console.log("tempCurrentTopicTreeNodeExpandedKeys--->", tempCurrentTopicTreeNodeExpandedKeys)
            //     setCurrentTopicTreeNodeExpandedKeys(deepCloneV2(tempCurrentTopicTreeNodeExpandedKeys))
            // }
            //3、滚动
            currentTopicTreeRef.current.scrollTo({ key: targetNodeId })
            setTimeout(() => {
                currentTopicTreeRef.current.scrollTo({ key: targetNodeId })
            }, 50);
        }
    };

    const checkTreeNodeHasChecked = (node) => {
        return checkedTopicIdList.includes(node.id);
    }

    //当前大纲的树形数据
    const currentTopicTree = useMemo(() => {
        let _tree = generateTreeData(addTreePropertyForList(topicList));
        // _tree = filterTree(_tree, (node) => (node.checked && node.topicType == 'text') || node.topicType == 'device');
        // const __tree = filterTree(_tree, (node) => node.checked == true);
        dfsRecursive(_tree, (topic: TopicType, level: number) => {
            if (topic.topicType == 'text') {
                const childDeviceNodeCount = getNodeChildDeviceNodeCount(topic);
                const childDeviceNodeCheckedCount = getNodeChildDeviceNodeCheckedCount(topic);
                topic.childDeviceNodeCount = childDeviceNodeCount;
                topic.childDeviceNodeCheckedCount = childDeviceNodeCheckedCount;
            }
            // if(topic.topicName == "资源与环境保护规划"){
            //     console.log("资源与环境保护规划--->", topic);
            // }
        })
        const currentTopicTreeData: TopicType[] = deepCloneV2(_tree);
        const currentTopicPureTextTopicTreeData = filterTree(currentTopicTreeData, (node) => {
            return node.topicType == 'text' && node.realCheckedStatus !== 'noChecked';
        });
        let serialNumberList = [];
        dfsRecursive(currentTopicPureTextTopicTreeData, (topic: TopicType, level: number) => {
            if (topic.topicType == 'text') {
                if (serialNumberList.length > level) {
                    serialNumberList = serialNumberList.splice(0, level + 1)
                    serialNumberList[serialNumberList.length - 1]++;
                } else if (serialNumberList.length == level) {
                    if (isEmpty(serialNumberList[level])) {
                        serialNumberList[level] = 1;
                    } else {
                        serialNumberList[level]++;
                    }
                } else {
                    serialNumberList.push(1)
                }
                const serialNumber = serialNumberList.join('.');
                topic.treeLevel = level;
                topic.serialNumber = serialNumber;
            }
        })
        console.log("currentTopicPureTextTopicTreeData--->", currentTopicPureTextTopicTreeData)
        return currentTopicPureTextTopicTreeData;
        // return currentTopicTreeData;
    }, [topicList, checkedTopicIdList])

    //所有大纲的树形数据
    const allTopicTree = useMemo(() => {
        let _tempTopicList = topicList.map(topic => {
            let newTopic = { ...topic };
            delete newTopic.children;
            return newTopic;
        })
        const _tree = generateTreeData(addTreePropertyForList(_tempTopicList));
        let serialNumberList = [];
        dfsRecursive(_tree, (topic: TopicType, level: number) => {
            if (topic.topicType == 'text') {
                if (serialNumberList.length > level) {
                    serialNumberList = serialNumberList.splice(0, level + 1)
                    serialNumberList[serialNumberList.length - 1]++;
                } else if (serialNumberList.length == level) {
                    if (isEmpty(serialNumberList[level])) {
                        serialNumberList[level] = 1;
                    } else {
                        serialNumberList[level]++;
                    }
                } else {
                    serialNumberList.push(1)
                }
                const serialNumber = serialNumberList.join('.');
                topic.serialNumber = serialNumber;
            }
        })
        let allTopicTreeData: TopicType[] = deepCloneV2(_tree);
        return allTopicTreeData;
    }, [topicList, checkedTopicIdList])

    useEffect(() => {
        _setComDocInstance({ ...debouncedComDocInstance })
    }, [debouncedComDocInstance])

    const handleUpdateComDocInstance = (newComDocInstance: DocInstance) => {
        newComDocInstance = { ...newComDocInstance };
        let _newComDocInstance = processDocInstanceBeforeUpdate(newComDocInstance);
        _newComDocInstance.updateComponentName = 'TopicSliderBar';
        _newComDocInstance.topicList = newComDocInstance.topicList.map(topic => {
            delete topic.children;
            return topic;
        })
        tempComDocInstance.current = _newComDocInstance;
        setDelayUpdateComDocInstance({ ..._newComDocInstance });
    }

    const measureSettingBtnPosition = () => {
        const clientRect = topicSiderRef.current.getBoundingClientRect();
        const { top, right } = clientRect;
        setTopicSettingBtnPosition({ x: right - 56, y: 188 })
    }

    const onSliderTrackMounseMove = (e: any) => {
        if (isTopicSliderDragging.current) {
            if (e.clientX > 234 && e.clientX < 520) {
                topicSiderRef.current.style.width = e.clientX + 'px';
                onHandleResize && onHandleResize(e.clientX);
                if (saveSideBarCacheDelayTimer.current) {
                    clearTimeout(saveSideBarCacheDelayTimer.current)
                }
                saveSideBarCacheDelayTimer.current = setTimeout(() => {
                    const sideBarCacheList: any[] = localStorage.getItem('sideBarCacheList') ? JSON.parse(localStorage.getItem('sideBarCacheList')) : [];
                    const findSideBarCache = sideBarCacheList.find(item => {
                        return item.id = comDocInstance.id;
                    })
                    if (findSideBarCache) {
                        findSideBarCache.sideBarWidth = e.clientX;
                    } else {
                        sideBarCacheList.push({
                            id: comDocInstance.id,
                            sideBarWidth: e.clientX
                        })
                    }
                    localStorage.setItem('sideBarCacheList', JSON.stringify(sideBarCacheList));
                }, 2000);
            } else {
                // toastShort('warning', '已达拖放极限')
            }
        }
    }

    const onNodeContextMenu = (e: React.MouseEvent<HTMLDivElement, MouseEvent>, node: TopicType) => {
        if (!isEmpty(topicSearchValue)) {
            toastShort('warning', '请退出搜索模式后重试');
            return false;
        }
        e.preventDefault();
        e.stopPropagation();
        setCurrentHighLightTopicNode(node)
        setCurrentSelectedTopicNode(node);
        let originX = e.clientX;
        let originY = e.clientY;
        if (originY + 268 > windowFullHeight) {
            originY = windowFullHeight - 350;
        }
        e.clientX = originX;
        e.clientY = originY;
        contextMenuRef.current.showContextMenu(e);
    }

    const adaptNodeIcon = (node: TopicType) => {
        let nodeIcon = <i className='iconfont-1 ghzs-gray-shebei' />;
        switch (node.topicType) {
            case 'device':
                switch (node.deviceType) {
                    case 'S':
                        nodeIcon = <i className='iconfont-1 ghzs-gray-sheshi' />
                        break;
                    case 'X':
                        nodeIcon = <i className='iconfont-1 ghzs-gray-shebei' />

                        break;
                }
                break;
            case 'text':
                nodeIcon = <i className='iconfont-1 ghzs-gray-wenben' />
                break;
            default:
                break;
        }
        return (
            <div
                className='flex-row topic-tree-node-icon'
                style={{ width: currentcomDocConfig.docBaseConfigInfo?.showTopicTreeIcon ? 15 : 0 }}
            >
                {nodeIcon}
            </div>
        );
    }

    const adaptNodeSerialNumber = (node: TopicType) => {
        if (node.topicType == 'device') {
            return null;
        }
        return (
            <div
                className='topic-tree-node-extra'
                style={{ maxWidth: currentcomDocConfig.docBaseConfigInfo?.showTopicTreeLevel ? 120 : 0 }}
            >
                {node.serialNumber}&nbsp;
            </div>
        )
    }

    const formatSearchTextForCurrentTopicTree = (originStr: string) => {
        try {
            if (isEmpty(currentTopicSearchValue)) {
                return originStr;
            }
            let reg = new RegExp(currentTopicSearchValue);
            let str = originStr.split(reg);
            let txt = [];
            if (str.length === 0 || str.length === 1) {
                return originStr
            }
            if (str.length > 0) {
                txt.push(<span key={'0-0'}>{str[0]}</span>);
            }
            txt.push(<span key={'0-1'} style={{ color: '#ff0000' }}>{currentTopicSearchValue}</span>);
            if (str.length > 1) {
                txt.push(<span key={'0-2'}>{str[1]}</span>);
            }
            if (str.length >= 3) {
                for (let i = 2; i < str.length; i++) {
                    txt.push(<span key={'0-3'} style={{ color: '#ff0000' }}>{currentTopicSearchValue}</span>);
                    txt.push(<span key={'0-4'}>{str[i]}</span>);
                }
            }
            return txt;
        } catch (e) {
            return originStr;
        }
    }

    const formatSearchTextForAllTopicTree = (originStr: string) => {
        try {
            if (isEmpty(topicSearchValue)) {
                return originStr;
            }
            let reg = new RegExp(topicSearchValue);
            let str = originStr.split(reg);
            let txt = [];
            if (str.length === 0 || str.length === 1) {
                return originStr
            }
            if (str.length > 0) {
                txt.push(<span key={'0-0'}>{str[0]}</span>);
            }
            txt.push(<span key={'0-1'} style={{ color: '#ff0000' }}>{topicSearchValue}</span>);
            if (str.length > 1) {
                txt.push(<span key={'0-2'}>{str[1]}</span>);
            }
            if (str.length >= 3) {
                for (let i = 2; i < str.length; i++) {
                    txt.push(<span key={'0-3'} style={{ color: '#ff0000' }}>{topicSearchValue}</span>);
                    txt.push(<span key={'0-4'}>{str[i]}</span>);
                }
            }
            return txt;
        } catch (e) {
            return originStr;
        }
    }

    const renderCurrentTopicTreeNode = (node: TopicType) => {
        const isDragging = node.key === draggingNodeKey;
        const className = isDragging ? 'draggingNode' : '';
        return (
            <div
                className={makeClassNameList(['custom-tree-node', className])}
                key={node.id}
                onContextMenu={(e) => onNodeContextMenu(e, node)}
                style={currentHighLightTopicNode && currentHighLightTopicNode.id == node.id ? { backgroundColor: '#f2f2f2' } : null}
                //@ts-ignore
                datakey={node.key}
            >
                <div className='flex-row topic-tree-node'>
                    {/* {node.checked + '-'} */}
                    {adaptNodeSerialNumber(node)}
                    {adaptNodeIcon(node)}
                    <div className='single-line-text' style={{ maxWidth: 580, fontWeight: node.topicType == 'text' ? 'normal' : 'bold' }}>
                        {formatSearchTextForCurrentTopicTree(node.title)}
                        {/* -{node.id} */}
                        {/* -{node.checked + ''}
                        -{node.realCheckedStatus + ''} */}
                    </div>
                    {/* {
                        node.topicType == 'text' && node.directDeviceChildNodeCount ?
                            <Tooltip
                                title={"本节选择项目数量"}
                            >
                                <div className='flex-row device-manage-tree-node-count'>{node.directDeviceChildNodeCount}</div>
                            </Tooltip>
                            :
                            null
                    } */}
                    {/* {
                        node.topicType == 'text' && node.childDeviceNodeCount ?
                            <Tooltip
                                title={"本节包含项目总数量"}
                            >
                                <div className='flex-row device-manage-tree-node-total-count'>{node.childDeviceNodeCount}</div>
                            </Tooltip>
                            :
                            null
                    } */}
                    {
                        node.topicType == 'text' && node.childDeviceNodeCheckedCount ?
                            <Tooltip
                                title={"本节选择项目总数量"}
                            >
                                <div className='flex-row device-manage-tree-node-count'>{node.childDeviceNodeCheckedCount}</div>
                            </Tooltip>
                            :
                            null
                    }
                </div>
            </div>
        );
    }

    const renderAllTopicTreeNode = (node: TopicType) => {
        return (
            <div
                className='custom-tree-node'
                key={node.id}
                onContextMenu={(e) => onNodeContextMenu(e, node)}
                style={currentHighLightTopicNode && currentHighLightTopicNode.id == node.id ? { backgroundColor: '#f2f2f2' } : null}
            >
                <div className='flex-row topic-tree-node'>
                    {/* {node.id}- */}
                    {adaptNodeSerialNumber(node)}
                    {adaptNodeIcon(node)}
                    <div className='single-line-text' style={{ maxWidth: 420, fontWeight: node.topicType == 'text' ? 'normal' : 'bold' }}>
                        {formatSearchTextForAllTopicTree(node.title)}
                        {/* -{node.id} */}
                    </div>
                </div>
            </div>
        );
    }

    /**
     * 
     * @param checkedNodeIdList 
     */
    const onTreeNodeCheckedChange = (checkedNodeIdList: string[]) => {
        // console.log("onTreeNodeCheckedChange---->", checkedNodeIdList);
        // let _tempTopicList = tempTopicList.current;
        let _tempTopicList = topicList;
        let _tempComDocInstance = tempComDocInstance.current;
        if (!isEmpty(topicSearchValue)) {
            //如果是搜索模式，则需要把搜索树和整体树合并处理
            //第一、搜索树的勾选节点列表代表了搜索树的全部勾选情况
            //第二、根据缓存的全部树已勾选节点信息，取出不与搜索树相交的勾选节点
            //第三、把两者合并并同步到topicTreeCheckedNodeIdList、和allTopicTreeSelectNodeIdList.current;
            const filteredTopicList: TopicType[] = tree2List([...filteredForAllTopicTree]);
            const tempAllTopicTreeSelectNodeIdList = allTopicTreeSelectNodeIdList.current;
            const tempDiffTopicTreeSelectNodeIdList = [];
            tempAllTopicTreeSelectNodeIdList.forEach(id => {
                const find = filteredTopicList.find(node => {
                    return node.id == id;
                })
                if (!find) {
                    tempDiffTopicTreeSelectNodeIdList.push(id)
                }
            })
            const mergedTopicTreeSelectNodeIdList = tempDiffTopicTreeSelectNodeIdList.concat(checkedNodeIdList);
            setTopicTreeCheckedNodeIdList(mergedTopicTreeSelectNodeIdList);
            allTopicTreeSelectNodeIdList.current = mergedTopicTreeSelectNodeIdList;
            let _tempTopicList = tempTopicList.current;
            _tempTopicList.forEach(topic => {
                if (mergedTopicTreeSelectNodeIdList.includes(topic.id)) {
                    topic.checked = true;
                } else {
                    topic.checked = false;
                }
            })
        } else {
            setTopicTreeCheckedNodeIdList(checkedNodeIdList);
            allTopicTreeSelectNodeIdList.current = checkedNodeIdList;
            _tempTopicList.forEach(topic => {
                if (checkedNodeIdList.includes(topic.id)) {
                    topic.checked = true;
                } else {
                    topic.checked = false;
                }
            })
        }
        _tempTopicList = deepCloneV2(_tempTopicList);
        setTopicList(_tempTopicList);
        tempTopicList.current = _tempTopicList;
        _tempComDocInstance.topicList = _tempTopicList;
        handleUpdateComDocInstance(_tempComDocInstance);
    };

    const onCurrentTopicTreeExpand = (expandedKeys: string[]) => {
        console.log("expandedKeys---->", expandedKeys);
        if (!isEmpty(currentTopicSearchValue)) {
            setFilteredForCurrentTopicTreeExpandedKeys(expandedKeys);
            return false;
        } else {
            if (expandedKeys.toString() === currentTopicTreeNodeExpandedKeys.toString()) {
                return false;
            }
            if (comDocConfig.docBaseConfigInfo?.topicTreeLinkage) {
                setAllTopicTreeExpandedKeys(expandedKeys);
            }
            setCurrentTopicTreeNodeExpandedKeys(expandedKeys)
        }
    }

    const onAllTreeNodeExpand = (expandedKeys: string[]) => {
        if (!isEmpty(topicSearchValue)) {
            setFilteredForAllTopicTreeExpandedKeys(expandedKeys);
            return false;
        } else {
            if (expandedKeys.toString() === allTopicTreeExpandedKeys.toString()) {
                return false
            }
            setAllTopicTreeExpandedKeys(expandedKeys);
            if (comDocConfig.docBaseConfigInfo?.topicTreeLinkage) {
                setCurrentTopicTreeNodeExpandedKeys(expandedKeys)
            }
        }
    }

    const onSelectCurrentTopicNode = (id: string[]) => {
        // console.log("onSelectCurrentTopicNode--->")
        if (selectTreeTimer) {
            clearTimeout(selectTreeTimer.current)
        }
        selectTreeTimer.current = setTimeout(() => {
            const findTopicNode = tempTopicList.current.find(ele => {
                return ele.id == id[0];
            })
            setCurrentSelectedTopicNode(findTopicNode);
            _setComFocusTopicNode(findTopicNode ? findTopicNode : null);
        }, 500);
    }

    const arrayTreeFilter = (data, predicate, filterText) => {
        const nodes = data;
        if (!(nodes && nodes.length)) {
            return;
        }
        const newChildren = [];
        for (const node of nodes) {
            if (predicate(node, filterText)) {
                // 如果自己（节点）符合条件，直接加入到新的节点集
                newChildren.push(node);
                // 并接着处理其 children,（因为父节点符合，子节点一定要在，所以这一步就不递归了）
                node.children = arrayTreeFilter(node.children, predicate, filterText);
            } else {
                // 如果自己不符合条件，需要根据子集来判断它是否将其加入新节点集
                // 根据递归调用 arrayTreeFilter() 的返回值来判断
                const subs = arrayTreeFilter(node.children, predicate, filterText);
                if ((subs && subs.length) || predicate(node, filterText)) {
                    node.children = subs;
                    newChildren.push(node);
                }
            }
        }
        return newChildren;
    }

    const filterFn = (data, filterText) => {
        if (!filterText) {
            return true;
        }
        return (
            new RegExp(filterText, "i").test(data.title)
        );
    }

    const expandedKeysFun = (treeData) => {
        if (treeData && treeData.length == 0) {
            return [];
        }
        let arr = [];
        const expandedKeysFn = (treeData) => {
            treeData.map((item, index) => {
                arr.push(item.key);
                if (item.children && item.children.length > 0) {
                    expandedKeysFn(item.children);
                }
            })
        }
        expandedKeysFn(treeData);
        return arr;
    }

    const onTopicSearchValueChange = (e: ChangeEvent<HTMLInputElement>) => {
        const newTopicSearchValue = getChangeEventValue(e);
        setTopicSearchValue(getChangeEventValue(e));
        if (!isEmpty(newTopicSearchValue)) {
            let tempFilteredTopicTree = arrayTreeFilter(deepCloneV2(allTopicTree), filterFn, newTopicSearchValue);
            let tempFilteredTopicTreeExpandedKeys = expandedKeysFun(tempFilteredTopicTree);
            setFilteredForAllTopicTree(tempFilteredTopicTree);
            setFilteredForAllTopicTreeExpandedKeys(tempFilteredTopicTreeExpandedKeys);
        }
    };

    const onCurrentTopicSearchValueChange = (e: ChangeEvent<HTMLInputElement>) => {
        const newTopicSearchValue = getChangeEventValue(e);
        setCurrentTopicSearchValue(getChangeEventValue(e));
        if (!isEmpty(newTopicSearchValue)) {
            let tempFilteredTopicTree = arrayTreeFilter(deepCloneV2(currentTopicTree), filterFn, newTopicSearchValue);
            let tempFilteredTopicTreeExpandedKeys = expandedKeysFun(tempFilteredTopicTree);
            setFilteredForCurrentTopicTree(tempFilteredTopicTree);
            setFilteredForCurrentTopicTreeExpandedKeys(tempFilteredTopicTreeExpandedKeys);
        }
    };

    const adaptCurrentTopicTreeExpandedKeys = useMemo(() => {
        if (isEmpty(currentTopicSearchValue)) {
            return currentTopicTreeNodeExpandedKeys
        } else {
            return filteredForCurrentTopicTreeExpandedKeys
        }
    }, [currentTopicSearchValue, currentTopicTreeNodeExpandedKeys, filteredForCurrentTopicTreeExpandedKeys]);

    const adaptAllTopicTreeExpandedKeys = () => {
        let tempAllTopicTreeSelectNodeIdList: string[] = [];
        if (isEmpty(topicSearchValue)) {
            tempAllTopicTreeSelectNodeIdList = allTopicTreeExpandedKeys
        } else {
            tempAllTopicTreeSelectNodeIdList = filteredForAllTopicTreeExpandedKeys
        }
        return tempAllTopicTreeSelectNodeIdList;
    };

    const onContextMenuClose = () => {
        setCurrentHighLightTopicNode(null);
    }

    const onClickTopicSetting = () => {
        topicSettingPopoverRef.current.openPopover();
    }

    const onClickTopicManage = () => {
        deviceNodeManageModalRef.current.openModal({
            type: 'topicList',
            topicList: deepCloneV2(tempTopicList.current),
        })
    };

    /**
     * 添加指定树节点下的子节点
     * @param tree 
     * @param list 
     * @param targetNodeId 
     */
    const insertChildNodeListToTree = (tree: TopicType[], list: TopicType[], targetNodeId: string) => {
        tree.forEach(node => {
            if (node.id == targetNodeId) {
                list && list.length && list.forEach(item => {
                    item.pid = targetNodeId;
                })
                if (node.children && node.children.length) {
                    node.children = node.children.concat(list);
                } else {
                    node.children = list;
                }
            } else if (node.children) {
                insertChildNodeListToTree(node.children, list, targetNodeId)
            }
        })
    }

    const insertPeerNodeListToTree = (tree: TopicType[], list: TopicType[], targetNodeId: string) => {
        list.forEach(topic => {
            topic.wordParagraphList = [];
        })
        tree.forEach((node, index, array) => {
            if (node.children && node.children.length) {
                let targetIndex = node.children.findIndex(subNode => subNode.id === targetNodeId);
                if (targetIndex !== -1) {
                    list.forEach(item => {
                        item.pid = node.id;
                    });
                    node.children.splice(targetIndex + 1, 0, ...list);
                } else {
                    insertPeerNodeListToTree(node.children, list, targetNodeId);
                }
            }
        });
    };

    const insertTopPeerNodeListToTree = (tree: TopicType[], list: TopicType[], targetNodeId: string) => {
        let findTopTagetNodeIndex = -1;
        tree.forEach((node, nodeIndex) => {
            if (node.id == targetNodeId) {
                findTopTagetNodeIndex = nodeIndex;
            }
        })
        list.forEach(item => {
            item.pid = '0';
        })
        let tempTreeData = tree;
        if (findTopTagetNodeIndex > -1) {
            const lastArr = tempTreeData.splice(findTopTagetNodeIndex + 1, tree.length - 1);
            tempTreeData = tempTreeData.concat(list).concat(lastArr)
        }
        return tempTreeData;
    }

    const moveNode = (nodeList: TopicType[], targetId: string, direction: 'up' | 'down' | 'top' | 'bottom'): TopicType[] => {
        let findIndex = -1;
        if (nodeList.length == 0 || nodeList.length == 1) {
            return nodeList;
        }
        for (let i = 0; i < nodeList.length; i++) {
            if (nodeList[i].id == targetId) {
                findIndex = i;
                break;
            }
        }
        if (findIndex > -1) {
            const targetNodePid = nodeList[findIndex].pid;
            switch (direction) {
                case 'top':
                    let needToMoveDownNodeIndexList: number[] = [];
                    for (let i = 0; i < nodeList.length; i++) {
                        if (nodeList[i].pid == targetNodePid) {
                            if (i <= findIndex) {
                                needToMoveDownNodeIndexList.push(i)
                            }
                        }
                    }
                    if (needToMoveDownNodeIndexList[0] == findIndex) {
                        toastShort('warning', '该节点已置顶，请勿重复操作')
                    } else {
                        toastShort('success', commonSuccessMsg)
                        let _nodeList = nodeList;
                        for (let i = needToMoveDownNodeIndexList.length - 1; i > 0; i--) {
                            const currentNodeIndex = needToMoveDownNodeIndexList[i];
                            const currentNodeBeforeIndex = needToMoveDownNodeIndexList[i - 1];
                            _nodeList = swapListElements(_nodeList, currentNodeBeforeIndex, currentNodeIndex);
                        }
                        return _nodeList;
                    }
                    break;
                case 'bottom':
                    let needToMoveUpNodeIndexList: number[] = [];
                    for (let i = 0; i < nodeList.length; i++) {
                        if (nodeList[i].pid == targetNodePid) {
                            if (i >= findIndex) {
                                needToMoveUpNodeIndexList.push(i)
                            }
                        }
                    }
                    if (needToMoveUpNodeIndexList[needToMoveUpNodeIndexList.length - 1] == findIndex) {
                        toastShort('warning', '该节点已置底，请勿重复操作')
                    } else {
                        toastShort('success', commonSuccessMsg)
                        let _nodeList = nodeList;
                        for (let i = 0; i < needToMoveUpNodeIndexList.length; i++) {
                            const currentNodeIndex = needToMoveUpNodeIndexList[i];
                            const currentNodeBeforeIndex = needToMoveUpNodeIndexList[i - 1];
                            _nodeList = swapListElements(_nodeList, currentNodeBeforeIndex, currentNodeIndex);
                        }
                        return _nodeList;
                    }
                    break;
                case 'up':
                    if (
                        nodeList[findIndex - 1] &&
                        nodeList[findIndex - 1].pid == targetNodePid
                    ) {
                        let currentChildrenNodeIndexList: number[] = [];
                        for (let i = 0; i < nodeList.length; i++) {
                            if (nodeList[i].pid == targetNodePid) {
                                if (i <= findIndex) {
                                    currentChildrenNodeIndexList.push(i)
                                }
                            }
                        }
                        let _nodeList = nodeList;
                        _nodeList = swapListElements(_nodeList, currentChildrenNodeIndexList[currentChildrenNodeIndexList.length - 2], currentChildrenNodeIndexList[currentChildrenNodeIndexList.length - 1]);
                        toastShort('success', commonSuccessMsg)
                        return _nodeList;
                    } else {
                        toastShort('warning', '该节点已置顶，不可继续上移')
                    }
                    break;
                case 'down':
                    if (nodeList[findIndex + 1] && nodeList[findIndex + 1].pid == targetNodePid) {
                        toastShort('success', commonSuccessMsg)
                        const _nodeList = swapListElements(nodeList, findIndex, findIndex + 1);
                        return _nodeList;
                    } else {
                        toastShort('warning', '该节点已置底，不可继续下移')
                    }
                    break;
                default:
                    break;
            }
            return nodeList;
        } else {
            toastShort('error', '节点不存在，请您刷新页面重试！')
        }
    }

    const handleMoveCurrentSelectedNode = (moveType: 'up' | 'down' | 'top' | 'bottom') => {
        try {
            let _tempComDocInstance = tempComDocInstance.current;
            let _tempTopicList = topicList;
            _tempTopicList = moveNode(_tempTopicList, currentSelectedTopicNode.id, moveType);
            _tempTopicList = deepCloneV2(_tempTopicList);
            tempTopicList.current = _tempTopicList;
            setTopicList(_tempTopicList);
            //更新文档
            _tempComDocInstance.topicList = _tempTopicList;
            handleUpdateComDocInstance(_tempComDocInstance);
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    /**
     * 当选择1级contextMenu之后
     * @param actionType 
     */
    const onPickerTreeNodeActionType = (actionType: TopicNodeActionType) => {
        setCurrentTreeNodeActionType(actionType);
        switch (actionType) {
            case 'AddDeviceChildNode':
                // if(Number(currentSelectedTopicNode.topicLevel) >= 6){
                //     return toastShort('error', '大纲节点最多不能超过6级')
                // }
                addTopicModalRef.current.openModal();
                break;
            case 'AddTextChildNode':
                if (Number(currentSelectedTopicNode.topicLevel) >= 6) {
                    return toastShort('error', '大纲节点最多不能超过6级')
                }
                addTopicModalRef.current.openModal();
                break;
            case 'AddDevicePeerNode':
                addTopicModalRef.current.openModal();
                break;
            case 'AddTextPeerNode':
                addTopicModalRef.current.openModal();
                break;
            case 'MoveUp':
                handleMoveCurrentSelectedNode('up');
                break;
            case 'MoveDown':
                handleMoveCurrentSelectedNode('down');
                break;
            case 'MoveTop':
                handleMoveCurrentSelectedNode('top');
                break;
            case 'MoveBottom':
                handleMoveCurrentSelectedNode('bottom');
                break;
            case 'ReName':
                renameTopicModalRef.current.openModal(currentSelectedTopicNode.topicName);
                break;
            case 'Delete':
                handleDeleteCurrentSelectedNode();
                break;
            case 'UnChecked':
                handleUnCheckedCurrentSelectedNode();
                break;
            default:
                break;
        }
    }

    const [modal, contextHolder] = Modal.useModal();

    const handleUnCheckedCurrentSelectedNode = () => {
        modal.confirm({
            title: '温馨提示',
            icon: <ExclamationCircleOutlined />,
            content: '确认从本文大纲中移除此节点吗？移除后您可在大纲配置中重新勾选',
            okText: '确认',
            cancelText: '取消',
            centered: true,
            onOk: confirmToUnCheckedCurrentSelectedNode,
        });
    }

    const findTreePathByTargetNodeIdList = (treeData: TopicType[], nodeId: string) => {
        const map = new Map();
        // 建立每个节点与其父节点的映射
        function buildMap(node, parentId = null) {
            if (!node) return;
            map.set(node.id, parentId);
            if (node.children) {
                node.children.forEach(child => buildMap(child, node.id));
            }
        }
        // 遍历树数据，建立映射
        treeData.forEach(node => buildMap(node));
        // 从指定节点回溯到根节点
        const path = [];
        let currentId = nodeId;
        while (currentId !== null) {
            path.push(currentId);
            currentId = map.get(currentId);
        }
        return path.reverse(); // 反转数组，使其从根节点开始
    }

    const findAllDescendants = (treeData: TopicType[], nodeId: string) => {
        const result = [];
        function findDescendants(node) {
            if (!node || !node.children) return;
            node.children.forEach(child => {
                result.push(child.id);
                findDescendants(child);
            });
        }

        function findNodeAndDescendants(nodes) {
            for (let i = 0; i < nodes.length; i++) {
                if (nodes[i].id === nodeId) {
                    findDescendants(nodes[i]);
                    break;
                }
                if (nodes[i].children) {
                    findNodeAndDescendants(nodes[i].children);
                }
            }
        }
        findNodeAndDescendants(treeData);
        return result;
    }

    const confirmToUnCheckedCurrentSelectedNode = () => {
        try {
            // let _checkedTopicIdList = checkedTopicIdList;
            // //需要直接取消勾选的节点
            let needToUnCheckedIdList = findAllDescendants(currentTopicTree, currentSelectedTopicNode.id);
            // //需要取消勾选的节点(如果此节点是勾选的话);
            let needToUnCheckedIfNodeChecedIdList = findTreePathByTargetNodeIdList(currentTopicTree, currentSelectedTopicNode.id);
            // _checkedTopicIdList = _checkedTopicIdList.filter(id => {
            //     return id !== currentSelectedTopicNode.id && 
            //     // !needToUnCheckedIfNodeChecedIdList.includes(id) &&
            //     !needToUnCheckedIdList.includes(id)
            // });
            // onTreeNodeCheckedChange([..._checkedTopicIdList])
            let _tempComDocInstance = tempComDocInstance.current;
            let { topicList } = _tempComDocInstance;
            const tempTopicTreeData = generateTreeData(topicList);
            dfsRecursive(tempTopicTreeData, (node: TopicType) => {
                if (node.id == currentSelectedTopicNode.id) {
                    node.checked = false;
                }
                if (needToUnCheckedIdList.includes(node.id)) {
                    node.checked = false;
                }
                if (needToUnCheckedIfNodeChecedIdList.includes(node.id)) {
                    node.checked = false;
                }
            })
            _tempComDocInstance.topicList = deepCloneV2(tree2List(tempTopicTreeData));
            handleUpdateComDocInstance(_tempComDocInstance);
            toastShort('success', commonSuccessMsg)
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    const handleDeleteCurrentSelectedNode = () => {
        modal.confirm({
            title: '温馨提示',
            icon: <ExclamationCircleOutlined />,
            content: `确认删除此${currentSelectedTopicNode.topicType == 'device' ? '项目' : '大纲'}？`,
            okText: '确认',
            cancelText: '取消',
            centered: true,
            onOk: confirmToDeleteCurrentSelectedNode
        });
    }

    const confirmToDeleteCurrentSelectedNode = () => {
        try {
            let _tempComDocInstance = tempComDocInstance.current;
            let _tempTopicList = _tempComDocInstance.topicList;
            for (let i = 0; i < _tempTopicList.length; i++) {
                if (_tempTopicList[i].id == currentSelectedTopicNode.id) {
                    _tempTopicList.splice(i, 1);
                    break;
                }
            }
            _tempTopicList = deepCloneV2(_tempTopicList);
            tempTopicList.current = _tempTopicList;
            setTopicList(_tempTopicList);
            //更新文档
            _tempComDocInstance.topicList = _tempTopicList;
            handleUpdateComDocInstance(tempComDocInstance.current);
            toastShort('success', commonSuccessMsg)
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    /**
     * 第一步构造好树结构
     * 第二步把节点添加到树中
     * 第三步把树结构转换成topicList列表结构
     * 第四步触发树节点自动转换
     * @param newTopic 
     */
    const onChangeTopic = (newTopic: TopicType, originTopic: TopicType) => {
        try {
            let _tempTreeData = allTopicTree;
            let _checkedTopicIdList = checkedTopicIdList;
            if (originTopic) {
                deleteNode(originTopic.id, _tempTreeData)
            }
            newTopic.checked = true;
            newTopic.childrenDeviceTopicListLength = 0;
            _checkedTopicIdList.push(newTopic.id);
            setCheckedTopicIdList([..._checkedTopicIdList]);
            let _tempComDocInstance = tempComDocInstance.current;
            let newTopicNodeList = [newTopic];
            switch (currentTreeNodeActionType) {
                case 'AddDeviceChildNode':
                    console.log("AddDeviceChildNode---->")
                    insertChildNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    break;
                case 'AddTextChildNode':
                    insertChildNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    break;
                case 'AddDevicePeerNode':
                    if (currentSelectedTopicNode.pid == '0') {
                        _tempTreeData = insertTopPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    } else {
                        insertPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    }
                    break;
                case 'AddTextPeerNode':
                    if (currentSelectedTopicNode.pid == '0') {
                        _tempTreeData = insertTopPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    } else {
                        insertPeerNodeListToTree(_tempTreeData, newTopicNodeList, currentSelectedTopicNode.id)
                    }
                    break;
                default:
                    break;
            }
            let tempTopicNodeId: string = '';
            let tempTopicTreeCheckedNodeIdList = topicTreeCheckedNodeIdList;
            let testNodeId = newTopic.id;
            if (newTopic.checked) {
                tempTopicTreeCheckedNodeIdList.push(newTopic.id);
            } else {
                dfsRecursiveFromInner(_tempTreeData, (node: TopicType) => {
                    if (node.id == testNodeId) {
                        tempTopicNodeId = node.pid;
                    }
                    if (node.id == tempTopicNodeId) {
                        node.checked = false;
                        let findIndex = -1;
                        for (let i = 0; i < tempTopicTreeCheckedNodeIdList.length; i++) {
                            findIndex = i;
                            break;
                        }
                        if (findIndex != -1) {
                            tempTopicTreeCheckedNodeIdList.splice(findIndex, 1);
                        }
                        tempTopicNodeId = node.pid;
                    }
                })
            }
            const halfCheckeNodeList: string[] = findHalfCheckedKeys(_tempTreeData, tempTopicTreeCheckedNodeIdList);
            setCheckedTopicIdList(tempTopicTreeCheckedNodeIdList.concat(halfCheckeNodeList))
            const _tempTopicList = [...tree2List(_tempTreeData)];
            tempTopicList.current = _tempTopicList;
            setTopicList(_tempTopicList);
            //更新文档
            _tempComDocInstance.topicList = _tempTopicList;
            handleUpdateComDocInstance(_tempComDocInstance);
            toastShort('success', commonSuccessMsg)
        } catch (e) {
            toastShort('error', commonErrorMsg)
        }
    }

    const _onReNameFinish = (newName: string) => {
        let _tempComDocInstance = tempComDocInstance.current;
        let _tempTopicList = topicList;
        _tempTopicList.forEach(topic => {
            if (topic.id == currentSelectedTopicNode.id) {
                topic.topicName = newName;
            }
        })
        _tempTopicList = deepCloneV2(_tempTopicList);
        tempTopicList.current = _tempTopicList;
        setTopicList(_tempTopicList)
        _tempComDocInstance.topicList = _tempTopicList;
        handleUpdateComDocInstance(_tempComDocInstance);
    }

    const onDeviceNodeManageFinish = (newTopicList: TopicType[]) => {
        const _newTopicList = deepCloneV2(newTopicList);
        tempTopicList.current = _newTopicList;
        let _tempComDocInstance = tempComDocInstance.current;
        setTopicList(deepCloneV2(_newTopicList))
        _tempComDocInstance.topicList = newTopicList;
        handleUpdateComDocInstance(_tempComDocInstance);
    }

    const onActiveTabChange = (e: 'currentTopic' | 'allTopic') => {
        setCurrentActiveTabKey(e);
    }

    const disableDrag = () => {
        return false;
    }

    const onCollapsedAllNode = () => {
        setCurrentTopicTreeNodeExpandedKeys([]);
        setAllTopicTreeExpandedKeys([])
    }

    const onExpandedAllNode = () => {
        //当前大纲
        const currentTopicTreeData = currentTopicTree;
        let _currentTopicTreeNodeExpandedKeys = [];
        dfsRecursive(currentTopicTreeData, (node: TopicType) => {
            _currentTopicTreeNodeExpandedKeys.push(node.id)
        })
        setCurrentTopicTreeNodeExpandedKeys(_currentTopicTreeNodeExpandedKeys);
        //全部大纲
        const allTopicTreeData = allTopicTree;
        let _allTopicTreeNodeExpandedKeys = [];
        dfsRecursive(allTopicTreeData, (node: TopicType) => {
            _allTopicTreeNodeExpandedKeys.push(node.id)
        })
        setAllTopicTreeExpandedKeys(_allTopicTreeNodeExpandedKeys);
    }

    const onResizeStart = () => {
        isTopicSliderDragging.current = true;
    }

    const onResizeStop = () => {
        isTopicSliderDragging.current = false;
        setToolTipIsOpen(false)
    }

    const onSideBarResize = (e, resizeInfo) => {
        if (isTopicSliderDragging.current) {
            if (e.clientX > 234 && e.clientX < 520) {
                topicSiderRef.current.style.width = e.clientX + 'px';
                onHandleResize && onHandleResize(e.clientX);
                if (saveSideBarCacheDelayTimer.current) {
                    clearTimeout(saveSideBarCacheDelayTimer.current)
                }
                saveSideBarCacheDelayTimer.current = setTimeout(() => {
                    const sideBarCacheList: any[] = localStorage.getItem('sideBarCacheList') ? JSON.parse(localStorage.getItem('sideBarCacheList')) : [];
                    const findSideBarCache = sideBarCacheList.find(item => {
                        return item.id = comDocInstance.id;
                    })
                    if (findSideBarCache) {
                        findSideBarCache.sideBarWidth = e.clientX;
                    } else {
                        sideBarCacheList.push({
                            id: comDocInstance.id,
                            sideBarWidth: e.clientX
                        })
                    }
                    localStorage.setItem('sideBarCacheList', JSON.stringify(sideBarCacheList));
                }, 2000);
            } else {
                if (toastDelayTimer.current) {
                    return clearTimeout(toastDelayTimer.current);
                }
                toastDelayTimer.current = setTimeout(() => {
                    toastShort('warning', '已达拖放极限')
                }, 200);
            }
        }
    }

    const checkCurrentTopicTreeNodeDraggale = (e): boolean => {
        if (checkIsTopicSearchMode()) {
            return false;
        } else {
            return true;
        }
    }

    const onDragStart = (info) => {
        setDraggingNodeKey(info.node.key);
        // document.querySelector(`[data-tree-node-key="${info.node.key}"]`).classList.add('draggingNode');
    }

    const onDragLeave = (e) => {
        // console.log("onDragLeave--->", e)
    }

    const scrollTo = useCallback(

        throttle((target) => {
            const { bottom: currentBottom, top: currentTop } = target.getBoundingClientRect();
            const { bottom: boxBottom, top: boxTop } = document
                .getElementsByClassName('ant-tree-list-holder')[0]
                .getBoundingClientRect();
            if (currentTop > boxBottom - 48) {
                document.getElementsByClassName('ant-tree-list-holder')[0].scrollTop =
                    document.getElementsByClassName('ant-tree-list-holder')[0].scrollTop + 32;
            }
            if (boxTop + 48 > currentBottom) {
                document.getElementsByClassName('ant-tree-list-holder')[0].scrollTop =
                    document.getElementsByClassName('ant-tree-list-holder')[0].scrollTop - 32;
            }
        }, 100),
        [currentTopicTreeRef]
    );

    const onDragOver = (info: any) => {
        if (info.event.target) {
            scrollTo(info.event.target);
        }
    }

    const onDragEnter = (e) => {
    }

    const onDragEnd = (e) => {
        setDraggingNodeKey(null);
    }

    const traverseTree = (treeData: TopicType[], callback: Function) => {
        treeData.forEach((item, index) => {
            callback(item, index);
            if (item.children) {
                traverseTree(item.children, callback);
            }
        });
    };

    const findItem = (data, node, parentItem?) => {
        let findResult = null;
        data.find((item) => {
            if (item?.key === node?.key) {
                if (parentItem) {
                    item.parent = parentItem;
                    return (findResult = item);
                } else return (findResult = item);
            } else if (item?.children?.length) {
                return (findResult = findItem(item.children, node, item));
            }
        });
        return findResult;
    };

    const findNode = (key, data) => {
        let result;
        const find = (key, data) => {
            data.forEach(item => {
                if (item.key === key) {
                    result = item;
                } else if (item.children) {
                    find(key, item.children);
                }
            });
        };
        find(key, data);
        return result;
    };

    const deleteNode = (key, data) => {
        data.forEach((item, index, arr) => {
            if (item.key === key) {
                arr.splice(index, 1);
            } else if (item.children) {
                deleteNode(key, item.children);
            }
        });
    };

    const updateNodePid = (node: TopicType, pid: string): TopicType => {
        node.pid = pid;
        if (node.children) {
            node.children.forEach(child => updateNodePid(child, node.key));
        }
        return node;
    };

    // 根据位置查找节点
    const findNodeByPos = (pos, data, startPos = '') => {
        for (const item of data) {
            const currentPos = startPos ? `${startPos}-${item.key}` : item.key;
            if (currentPos === pos) {
                return item;
            }
            if (item.children) {
                const result = findNodeByPos(pos, item.children, currentPos);
                if (result) {
                    return result;
                }
            }
        }
        return null;
    };

    // 获取兄弟节点和父节点的 key
    const getSiblingsAndParent = (key, data, parentKey = null) => {
        for (const item of data) {
            if (item.key === key) {
                return { siblings: data, parentKey };
            }
            if (item.children) {
                const result = getSiblingsAndParent(key, item.children, item.key);
                if (result) return result;
            }
        }
        return null;
    };

    const checkIsTopicSearchMode = (): boolean => {
        return !isEmpty(topicSearchValue) || !isEmpty(currentTopicSearchValue);
    }

    const onTopicNodeDrop = (info) => {
        console.log("info--->", info)
        setDraggingNodeKey("");
        if (checkIsTopicSearchMode()) {
            toastShort('error', '搜索模式下不可使用拖拽功能');
            return;
        }
        const treeData = deepCloneV2(currentTopicTree);
        const topicListOfTreeData = tree2List(treeData);
        const dropKey = info.node.key;
        const dragKey = info.dragNode.key;
        const dropPos = info.node.pos.split('-');
        const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
        const targetNode = info.node;
        const dropNode = findNode(dropKey, treeData);
        const dragNode = findNode(dragKey, treeData);
        let newDragNode = dragNode;
        // 检查被拖拽节点的 topicType
        if (dropNode.topicType === 'device' && !info.dropToGap) {
            // 如果是 'device' 类型的节点，且不是拖拽到间隙（即将成为非叶子节点），则阻止拖拽
            toastShort('error', '当前节点不可拖拽在所选位置')
            return;
        }
        deleteNode(dragKey, treeData);
        if (info.dropToGap) {
            // 处理兄弟节点之间的拖拽
            // const siblingsAndParent = getSiblingsAndParent(dropKey, treeData);
            // const siblings = siblingsAndParent.siblings;
            // const parentKey = siblingsAndParent.parentKey;
            // const index = siblings.findIndex(item => item.key === dropKey);
            // if (dropPosition === -1) {
            //     siblings.splice(index, 0, dragNode);
            // } else {
            //     siblings.splice(index + 1, 0, dragNode);
            // }
            // newDragNode = updateNodePid(dragNode, parentKey);
            //新版本
            const siblingsAndParent = getSiblingsAndParent(dropKey, treeData);
            if (!siblingsAndParent) return; // 确保找到了兄弟节点和父节点

            const siblings = siblingsAndParent.siblings;
            const parentKey = siblingsAndParent.parentKey;
            const index = siblings.findIndex(item => item.key === dropKey);
            // 根据 dropPosition 判断插入位置
            if (dropPosition < 0) {
                siblings.splice(Math.max(0, index), 0, newDragNode); // 确保即使index为-1，也能正确处理
            } else {
                siblings.splice(index + 1, 0, newDragNode);
            }
            newDragNode = updateNodePid(newDragNode, parentKey);
        } else {
            //添加为子节点
            //这里还有一种情况，就是当节点拖拽到第一个时，也会被视为创建成子节点，所以被追加到末尾了
            if (dragNode && dragNode.pid == targetNode.id) {
                dfsRecursive(treeData, (node: TopicType) => {
                    if (node.id == targetNode.id) {
                        let findIndex = node.children.findIndex(topic => topic.id == dragNode.id);
                        let needToMoveDownNodeIndexList = [];
                        node.children.forEach((ele, index) => {
                            if (index <= findIndex) {
                                needToMoveDownNodeIndexList.push(index);
                            }
                        })
                        for (let i = needToMoveDownNodeIndexList.length - 1; i > 0; i--) {
                            const currentNodeIndex = needToMoveDownNodeIndexList[i];
                            const currentNodeBeforeIndex = needToMoveDownNodeIndexList[i - 1];
                            node.children = swapListElements(node.children, currentNodeBeforeIndex, currentNodeIndex);
                        }
                    }
                })
            } else {
                //这里才是真的被添加为子节点
                const dropNode = findNode(dropKey, treeData);
                if (dropNode.topicType === 'device') {
                    return;
                }
                dropNode.children = dropNode.children || [];
                dropNode.children.unshift(dragNode);
                newDragNode = updateNodePid(dragNode, dropNode.id);
            }
        }
        handleSetTreeData(treeData, newDragNode);
    }

    function reorderParentArrayBasedOnSubset(parent, subset) {
        const parentMap = new Map(parent.map(e => [e.id, e]));
        subset.forEach(subElement => {
            if (parentMap.has(subElement.id)) {
                // 直接在映射中更新元素属性
                Object.assign(parentMap.get(subElement.id), subElement);
            }
        });

        // 创建一个排序后的父集数组
        const sortedAndUpdatedParent = parent
            .filter(e => parentMap.has(e.id)) // 保证只包括现在还存在的元素
            .sort((a, b) => {
                // 使用子集的顺序来排序父集中的元素
                const indexA = subset.findIndex(e => e.id === a.id);
                const indexB = subset.findIndex(e => e.id === b.id);
                return indexA - indexB;
            });

        // 返回更新和排序后的父集
        return sortedAndUpdatedParent;
    }

    const handleSetTreeData = (treeData: TopicType[], newDragNode: TopicType) => {
        if (isEmpty(newDragNode.pid)) {
            newDragNode.pid = '0';
        }
        let _tempComDocInstance = tempComDocInstance.current;
        const currentTreeDataTopicList: TopicType[] = [...tree2List(treeData)];
        console.log("currentTreeDataTopicList--->", deepCloneV2(currentTreeDataTopicList));
        let _tempTopicList = [...topicList];
        currentTreeDataTopicList.forEach((ele, index) => {
            ele.index = index;
            if (newDragNode && ele.id == newDragNode.id) {
                ele = deepCloneV2(newDragNode)
            }
        })
        let newTopicList = reorderParentArrayBasedOnSubset(_tempTopicList, currentTreeDataTopicList);
        newTopicList = deepCloneV2(newTopicList);
        setTopicList(newTopicList);
        _tempComDocInstance.topicList = newTopicList;
        handleUpdateComDocInstance(_tempComDocInstance);
    }

    // const onTopicTreeNodeClick = (e, textTopic: any) => {
    //     console.log("点击节点---->", e, textTopic);
    //     const { clientX, clientY } = e;
    //     const deviceNodeList = tempTopicList.current.filter(node => node.topicType == 'device');
    //     deviceNodeManagePopUpRef.current.openPopover({ clientX, clientY }, textTopic, deepCloneV2(deviceNodeList));
    // }

    const renderTab = (type: 'currentTopic' | 'allTopic') => {
        if (type == 'currentTopic') {
            return (
                <div className='topic-sider-bar-content'>
                    <Search
                        placeholder={'搜索本文大纲关键字'}
                        size={'middle'}
                        style={{ marginBottom: 10 }}
                        allowClear
                        value={currentTopicSearchValue}
                        onChange={onCurrentTopicSearchValueChange}
                    />
                    <Tree
                        ref={currentTopicTreeRef}
                        key={type + ''}
                        style={{ width: '100%', overflow: 'hidden' }}
                        showLine
                        draggable={{
                            icon: false,
                            nodeDraggable: checkCurrentTopicTreeNodeDraggale,
                        }}
                        autoExpandParent={false}
                        defaultExpandAll={false}
                        switcherIcon={<DownOutlined />}
                        checkable={false}
                        // activeKey={currentTopicTreeActiveNodeKey}
                        //@ts-ignore
                        titleRender={renderCurrentTopicTreeNode}
                        expandedKeys={adaptCurrentTopicTreeExpandedKeys}
                        onExpand={onCurrentTopicTreeExpand}
                        // onDoubleClick={onTopicTreeNodeClick}
                        //@ts-ignore
                        treeData={isEmpty(currentTopicSearchValue) ? currentTopicTree : filteredForCurrentTopicTree}
                        selectedKeys={currentSelectedTopicNode ? [currentSelectedTopicNode.id] : []}
                        onSelect={onSelectCurrentTopicNode}
                        // height={windowFullHeight - 230}
                        height={windowFullHeight - 280}
                        blockNode
                        onDragStart={onDragStart}
                        onDragOver={onDragOver}
                        onDragLeave={onDragLeave}
                        onDragEnter={onDragEnter}
                        onDragEnd={onDragEnd}
                        onDrop={onTopicNodeDrop}
                    />
                </div>
            )
        } else {
            return (
                <div className='topic-sider-bar-content'>
                    <Search
                        placeholder={'搜索大纲库关键字'}
                        size={'middle'}
                        style={{ marginBottom: 10 }}
                        allowClear
                        value={topicSearchValue}
                        onChange={onTopicSearchValueChange}
                    />
                    <Tree
                        key={type + ''}
                        style={{ width: '100%' }}
                        showLine
                        defaultExpandAll={false}
                        checkedKeys={topicTreeCheckedNodeIdList}
                        // checkStrictly
                        switcherIcon={<DownOutlined />}
                        onCheck={onTreeNodeCheckedChange}
                        checkable
                        //@ts-ignore
                        titleRender={renderAllTopicTreeNode}
                        expandedKeys={adaptAllTopicTreeExpandedKeys()}
                        //@ts-ignore
                        treeData={isEmpty(topicSearchValue) ? allTopicTree : filteredForAllTopicTree}
                        selectedKeys={currentSelectedTopicNode ? [currentSelectedTopicNode.id] : []}
                        onExpand={onAllTreeNodeExpand}
                        onSelect={onSelectCurrentTopicNode}
                        height={windowFullHeight - 280}
                        blockNode
                    />
                </div>
            )
        }
    }

    const tabList = [
        {
            key: 'currentTopic',
            label: (
                <div
                    className='flex-row topic-side-title-item'
                >
                    {/* 本文大纲 */}
                    规划大纲
                </div>
            ),
            children: renderTab('currentTopic'),
        },
        // {
        //     key: 'allTopic',
        //     label: (
        //         <div
        //             className='flex-row topic-side-title-item'
        //         >
        //             大纲配置
        //         </div>),
        //     children: renderTab('allTopic'),
        // },
    ]


    const onClickTopicWidthSwitch = () => {
        if (sideBarSwitched == 2) {
            onHandleResize(234);
            setSideBarSwitched(0);
        } else if(sideBarSwitched == 1){
            onHandleResize(399);
            setSideBarSwitched(2);
        }else if(sideBarSwitched == 0){
            onHandleResize(299);
            setSideBarSwitched(1);
        }
        setToolTipIsOpen(false);
        
    }
    
    const getSideBarWidth = () => {
        switch(sideBarSwitched){
            case 0:
                return 234;
                break;
            case 1:
                return 299;
                break;
            case 2:
                return 399;
                break;
            default:
                break;
        }
    };

    return (
        <div
            ref={topicSiderRef}
            className='topic-sider-bar content-border content-border-radius flex-col'
            style={{ width: getSideBarWidth() }}
        >
            <Tabs
                defaultActiveKey={currentActiveTabKey}
                activeKey={currentActiveTabKey}
                items={tabList}
                className='topic-side-tabs disable-drag'
                onChange={onActiveTabChange}
                onDragStart={disableDrag}
                tabBarExtraContent={{
                    right: (
                        <div
                            className='flex-row'
                        >
                            {/* <Tooltip title={'管理规划大纲'}>
                                <Button
                                    type={'text'}
                                    // <PartitionOutlined />

                                    icon={<ConnectionPoint style={{ marginTop: 1 }} theme="outline" size="19" fill="#333" />}
                                    className='topic-side-tab-setting'
                                    onClick={onClickTopicManage}
                                    style={{ marginRight: -1 }}
                                >
                                </Button>
                            </Tooltip> */}
                            <Tooltip title={"展开所有级别大纲"}>
                                <Button
                                    type={'text'}
                                    icon={<ExpandAltOutlined style={{ transform: `rotateZ(-45deg)`, color: '#000', fontSize: 16 }} />}
                                    className='topic-side-tab-setting'
                                    onClick={onExpandedAllNode}
                                    style={{ marginRight: -3 }}
                                >
                                </Button>
                            </Tooltip>
                            <Tooltip title={"收起所有级别大纲"}>
                                <Button
                                    type={'text'}
                                    icon={<VerticalAlignMiddleOutlined style={{ color: '#000', fontSize: 17 }} />}
                                    className='topic-side-tab-setting'
                                    onClick={onCollapsedAllNode}
                                    style={{ marginRight: -3 }}
                                >
                                </Button>
                            </Tooltip>
                            <Button
                                type={'text'}
                                icon={<SettingConfig theme="outline" size="20" fill="#333" strokeWidth={4} />}
                                className='topic-side-tab-setting'
                                onClick={onClickTopicSetting}
                                style={{ marginRight: -3 }}
                            >
                            </Button>
                            <Tooltip
                                title={"切换大纲面板宽度, 右侧竖线可拖动侧栏宽度"}
                                open={toolTipIsOpen}
                            >
                                <Button
                                    icon={
                                        sideBarSwitched > 1 ?
                                            <ExpandRight theme="outline" size="20" fill="#333" strokeWidth={4} />
                                            :
                                            <ExpandLeft theme="outline" size="20" fill="#333" strokeWidth={4} />
                                    }
                                    type={'text'}
                                    className='topic-side-tab-swicth'
                                    style={{ marginRight: -3, marginLeft: 5 }}
                                    onClick={onClickTopicWidthSwitch}
                                    onMouseLeave={() => setToolTipIsOpen(false)}
                                    onMouseEnter={() => setToolTipIsOpen(true)}
                                />
                            </Tooltip>
                            <Resizable
                                onResize={onSideBarResize}
                                width={32}
                                height={12}
                                onResizeStart={onResizeStart}
                                onResizeStop={onResizeStop}
                            >
                                <div
                                    className='flex-row side-bar-drag'
                                >
                                    <div
                                        className='side-bar-drag-content'
                                    >
                                    </div>
                                </div>
                            </Resizable>
                        </div>
                    )
                }}
            />
            {/* <div
                className='topic-sider-bar-slider flex-col'
                onMouseEnter={showSliderTrack}
                onMouseLeave={onSliderAreaMounseLeave}
            >
                <div
                    onMouseUp={onSliderTrackMounseUp}
                    onMouseDown={onSliderTrackMounseDown}
                    className='topic-sider-bar-slider-track flex-col'
                >
                    <div
                        ref={topicSiderTrackRef}
                        className='topic-sider-bar-slider-track-content'
                    ></div>
                </div>
            </div> */}
            <TopicTreeContextMenu
                ref={contextMenuRef}
                currentScreen={currentActiveTabKey}
                onContextMenuClose={onContextMenuClose}
                currentTopicNode={currentSelectedTopicNode}
                onPickerActionType={onPickerTreeNodeActionType}
                allowOption={'just-text'}
            />
            <TopicSettingPopover
                ref={topicSettingPopoverRef}
                clientX={topicSettingBtnPosition.x}
                clientY={topicSettingBtnPosition.y}
                onCollapsedAllNode={onCollapsedAllNode}
                onExpandedAllNode={onExpandedAllNode}
            />
            <AddTopicMoal
                ref={addTopicModalRef}
                currentTopicNode={currentSelectedTopicNode}
                currentTreeNodeActionType={currentTreeNodeActionType}
                onFinish={onChangeTopic}
            />
            <ReNameTopicModal
                ref={renameTopicModalRef}
                onFinish={_onReNameFinish}
            />
            <DeviceNodeManagePopUp
                ref={deviceNodeManagePopUpRef}
            />
            <DeviceNodeManageModalV2
                ref={deviceNodeManageModalRef}
                onFinish={onDeviceNodeManageFinish}
            />
            {contextHolder}
        </div>
    )
}

export default forwardRef(TopicSiderBar)